/**
 * @author haixuanwo
 * @email haixuanwo_clark@hotmail.com
 * @date 2021-01-22
 * @brief libevent timer定时器
 */

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/queue.h>
#include <unistd.h>
#include <time.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

#ifdef EVENT__HAVE_SYS_TIME_H
#include <sys/time.h>
#endif

extern "C" {
#include <event2/event.h>
#include <event2/event_struct.h>
#include <event2/util.h>
#include <event2/event-config.h>
#include <event2/event_compat.h>
}

#include "timer.h"

static struct timeval lasttime;
static int event_is_persistent;

static void timeout_cb(evutil_socket_t fd, short event, void *arg)
{
	struct timeval newtime, difference;
	struct event *timeout = (struct event *)arg;
	double elapsed;

	evutil_gettimeofday(&newtime, NULL);
	evutil_timersub(&newtime, &lasttime, &difference);
	elapsed = difference.tv_sec +
	    (difference.tv_usec / 1.0e6);

	printf("timeout_cb called at %d: %.3f seconds elapsed.\n",
	    (int)newtime.tv_sec, elapsed);
	lasttime = newtime;

	if (! event_is_persistent) {
		static struct timeval tv = {0, 0};
		//evutil_timerclear(&tv);
		tv.tv_sec += 2;
		event_add(timeout, &tv);
	}
}

int timer_test(int argc, char **argv)
{
	struct event timeout;
	struct timeval tv;
	struct event_base *base;
	int flags;

	if (argc == 2 && !strcmp(argv[1], "-p")) {
		event_is_persistent = 1;
		flags = EV_PERSIST;
	} else {
		event_is_persistent = 0;
		flags = 0;
	}

	/* Initialize the event library */
	base = event_base_new();

	/* Initialize one event */
	event_assign(&timeout, base, -1, flags, timeout_cb, (void*) &timeout);

	evutil_timerclear(&tv);
	tv.tv_sec = 2;
	event_add(&timeout, &tv);

	evutil_gettimeofday(&lasttime, NULL);

	setbuf(stdout, NULL);
	setbuf(stderr, NULL);

	event_base_dispatch(base);
	return 0;
}

// ============================================

struct event ev;
struct timeval tv;

void timer_cb(int fd, short event, void *arg)
{
	printf("time_cb\n");
	event_add(&ev, &tv); // 重新注册
}

int timer_test1(int argc, char **argv)
{
	struct event_base *eventBase = NULL;

	// 初始化libevent库
	eventBase = event_init();
	tv.tv_sec = 1;
	tv.tv_usec = 0;

	// 初始化event结构体
	event_set(&ev, -1, 0, timer_cb, NULL);
	event_base_set(eventBase, &ev);

	// 注册事件
	event_add(&ev, &tv);

	// 循环、分发事件
	event_base_dispatch(eventBase);

	return 0;
}

